/* ========================================================================= */
/* ------------------------------------------------------------------------- */
/*!
  \file			cmndata.h
  \date			Feb 2012
  \author		TNick

  \brief		Contains the definition for CmnData class


*//*


 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 Please read COPYING and README files in root folder
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
/* ------------------------------------------------------------------------- */
/* ========================================================================= */
#ifndef __CMNDATA_INC__
#define __CMNDATA_INC__
//
//
//
//
/*  INCLUDES    ------------------------------------------------------------ */

#include	<QChar>
#include	<QString>

#include	<tree3d.h>

/*  INCLUDES    ============================================================ */
//
//
//
//
/*  CLASS    --------------------------------------------------------------- */

#ifndef	AddP
#	define	AddP(p,o)	(((char*)p) + o)
#	define	SubP(p,o)	(((char*)p) - o)
#endif


namespace	ObjD	{

class		CmnData;
class		Session;

/**
*	@brief groups the layout of the first portion of an element
*/
class		CmnData		: public Tree3DNode		{

	//
	//
	//
	//
	/*  DEFINITIONS    ----------------------------------------------------- */

public:


	/**
	*	@brief	switches regarding CmnData
	*/
	enum	Flags		{

		/**
		*	@brief	simply tell that all the flags are off
		*/
		FLG_NONE		= 0x00000000,




		/**
		*	@brief	the instance is a generic one
		*/
		FLG_GENERIC		= 0x00010000,


		/**
		*	@brief	the instance owns the name
		*/
		FLG_NAME_MINE	= 0x00020000,


		/**
		*	@brief	the instance owns the description
		*/
		FLG_DESCR_MINE	= 0x00040000,


		/**
		*	@brief	the instance is a proper target for free()
		*
		*	discard() will call free with this pointer;
		*/
		FLG_INDEP_CHUNK	= 0x00200000,


		/**
		*	@brief	tell if this instance is just a reference to template
		*
		*	For objects created from templates, the initial status is set
		*	with this flag. This means that the object inherits all the
		*	characteristics of the object it inherits. When a property
		*	needs to be changed the list of characteristics will be duplicated.
		*/
		FLG_SHADOW		= 0x00400000,




		/**
		*	@brief	for validation; defined flags
		*/
		FLG_CMN_MASK =
		/**/	FLG_DESCR_MINE |
		/**/	FLG_GENERIC |
		/**/	FLG_INDEP_CHUNK |
		/**/	FLG_NAME_MINE |
		/**/	FLG_SHADOW


	};


#ifdef	OBJECTSLIB_TESTS
	friend void		CmnData_Tests	( int&, int& );
#endif



	/*  DEFINITIONS    ===================================================== */
	//
	//
	//
	//
	/*  DATA    ------------------------------------------------------------ */

private:

	/**
	*	@brief	pointer to template object
	*/
	CmnData *			templ_;


	/**
	*	@brief	the name as an QChar array; first element tells it's lenght
	*
	*	This may either be owned by this object or may be part of the
	*	Session's string table, as shown by the flags.
	*
	*	The array is limited to 0xFFFF elements. The lenght does not include
	*	the count element nor the final zero element.
	*/
	QChar *				p_name_a_;


	/**
	*	@brief	the description as an QChar array; first element tells it's lenght
	*
	*	This may either be owned by this object or may be part of the
	*	Session's string table, as shown by the flags.
	*
	*	The array is limited to 0xFFFF elements. The lenght does not include
	*	the count element nor the final zero element.
	*/
	QChar *				p_descr_a_;


	/**
	*	@brief	switches regarding this instance
	*/
	Flags				flg_;




	/*  DATA    ============================================================ */
	//
	//
	//
	//
	/*  FUNCTIONS    ------------------------------------------------------- */

public:

		/**
		*	@brief	set-up a memory area as a CmnData; set its name
		*/
		void			init			(
				const char *	s_name,
				Session *		ses = NULL
				);


	//	/**
	//	*	@brief	set-up a memory area as a CmnData; set its name and description
	//	*/
	//	static void			init			(
	//			CmnData *		p_d,
	//			const char *	s_name,
	//			const char *	s_descr
	//			);


	//	/**
	//	*	@brief	create an instance based on a template
	//	*/
	//	static CmnData *	init			(
	//			CmnData *		tpl
	//			);


	//	/**
	//	*	@brief	set-up a memory area as a CmnData; set its name
	//	*/
	//	static void			init			(
	//			CmnData *		p_d,
	//			QString			s_name
	//			);


	//	/**
	//	*	@brief	set-up a memory area as a CmnData; set its name and description
	//	*/
	//	static void			init			(
	//			CmnData *		p_d,
	//			QString			s_name,
	//			QString			s_descr
	//			);





	/**
	*	@brief	releases the resources associated with this instance
	*/
	void				discard			( void );


	/**
	*	@brief	tells the name of this item in QString format
	*/
	QString				name			( void );


	/**
	*	@brief	tells the name of this item as pointer
	*
	*	Returned pointer may be compared against other pointers for equality
	*/
	QChar*				pName			( quint32 & n_len );


	/**
	*	@brief	tells the description of this item in QString format
	*/
	QString				descr			( void );


	/**
	*	@brief	tells the description of this item as pointer
	*
	*	Returned pointer may be compared against other pointers for equality
	*/
	QChar*				pDescr			( quint32 & n_len );




protected:



	/**
	*	@brief	get the NodeData associated with this structure
	*/
	inline Tree3DNode *	getNodeData		( void )
	{ return static_cast<Tree3DNode *>(this); }







public:

	/**
	*	@brief	tells if the instance is generic or not
	*/
	inline bool			isGeneric		( void )
	{ return isFlagSet( FLG_GENERIC ); }

protected:

	/**
	*	@brief	set the instance to be generic
	*/
	inline void			setGeneric		( void )
	{ return setFlag( FLG_GENERIC ); }

	/**
	*	@brief	set the instance not to be generic
	*/
	inline void			resetGeneric		( void )
	{ return setFlag( FLG_GENERIC ); }


protected:

	/**
	*	@brief	tells if the name is owned by this instance
	*/
	inline bool			ownsName			( void )
	{ return isFlagSet( FLG_NAME_MINE ); }

	/**
	*	@brief	set name owned by this instance
	*/
	inline void			setOwnsName			( void )
	{ return setFlag( FLG_NAME_MINE ); }

	/**
	*	@brief	set name not owned by this instance
	*/
	inline void			resetOwnsName		( void )
	{ return setFlag( FLG_NAME_MINE ); }



protected:

	/**
	*	@brief	tells if the description is owned by this instance
	*/
	inline bool			ownsDescr			( void )
	{ return isFlagSet( FLG_DESCR_MINE ); }

	/**
	*	@brief	set name owned by this instance
	*/
	inline void			setOwnsDescr		( void )
	{ return setFlag( FLG_DESCR_MINE ); }

	/**
	*	@brief	set name not owned by this instance
	*/
	inline void			resetOwnsDescr		( void )
	{ return setFlag( FLG_DESCR_MINE ); }






protected:

	/**
	*	@brief	tell if the instance is a proper target for free()
	*
	*	discard() will call free with this pointer
	*/
	inline bool			isIndependent		( void )
	{ return isFlagSet( FLG_INDEP_CHUNK ); }

	/**
	*	@brief	set name owned by this instance
	*/
	inline void			setIndependent		( void )
	{ return setFlag( FLG_INDEP_CHUNK ); }

	/**
	*	@brief	set name not owned by this instance
	*/
	inline void			resetIndependent	( void )
	{ return setFlag( FLG_INDEP_CHUNK ); }



protected:

	/**
	*	@brief	tell if this instance is just a reference to template
	*
	*	For objects created frm templates, the initial status is set
	*	with this flag. This means that the object inherits all the
	*	characteristics of the object it inherits. When a property
	*	needs to be changed the list of characteristics will be duplicated.
	*/
	inline bool			isShadow		( void )
	{ return isFlagSet( FLG_SHADOW ); }

	/**
	*	@brief	set this to be a reference to template
	*/
	inline void			setShadow		( void )
	{ return setFlag( FLG_SHADOW ); }

	/**
	*	@brief	no longer a reference to template
	*/
	inline void			resetShadow	( void )
	{ return setFlag( FLG_SHADOW ); }





protected:

	/**
	*	@brief	set one of the switches to on (1)
	*/
	inline void		setFlag				( int new_flg )
	{ flg_ = static_cast<Flags> ( flg_ | new_flg ); }


	/**
	*	@brief	set one of the switches to of (0)
	*/
	inline void		resetFlag			( int new_flg )
	{ flg_ = static_cast<Flags> ( flg_ & ( ~new_flg ) ); }


	/**
	*	@brief	tell if  switch is on (true) or off (false)
	*/
	inline bool		isFlagSet			( int flg_val )
	{ return ( ( flg_ & flg_val ) != 0 ); }



	/*  FUNCTIONS    ======================================================= */
	//
	//
	//
	//

};	/*	class CmnData	*/

/*  CLASS    =============================================================== */
//
//
//
//

#ifdef	OBJECTSLIB_TESTS
void				CmnData_Tests					(
		int & performed, int & succeded );
#endif

}	//	namespace	ObjD

#endif // __CMNDATA_INC__
/* ------------------------------------------------------------------------- */
/* ========================================================================= */
